// 引入sme-router
import smeRouter from 'sme-router'
// 引入格式化时间的js包 moment
import moment from 'moment'

// 引入获取管理员数据的方法
import { getAdmins } from './api/admin'
import { reqLogin, reqVerifyToken, reqlogout } from './api/login'
import {
  reqAddAdv,
  getAdvs,
  deleteAdv,
  getOneAdv,
  reqUpdateAdv,
} from './api/adv'

// 引入ejs模板
import index from 'v/index'
import login from 'v/login'
import adminList from 'v/adminList'
import advList from 'v/advList'

// 实例化smeRouter
// smeRouter默认使用hash模式， 如果第二个参数为html5,则smeRouter使用history模式
const router = new smeRouter('root', 'html5')
// 将router添加到window,上.这样.哪里都可以获取到router
window.router = router
// router.go('目标路径') 可以修改地址栏路径,但是不发送请求
// 将moment添加到window上.这样哪里都可以直接访问moment
window.moment = moment

async function isEnableToken(res) {
  return new Promise(async (resolve, reject) => {
    const verifyResult = await reqVerifyToken()
    if (verifyResult.success) {
      resolve()
    } else {
      reject()
      //提示用户
      toastr.error(verifyResult.msg)
      //重定向登录
      res.redirect('/login')
    }
  })
}

// 定义前端路由规则
router.route('/login', (req, res, next) => {
  // req 是路径变化,页面要切换的时候的一些信息
  // res 提供了一些方法,可以在路径变化的时候,规定渲染什么,或重定向等
  // next 主要用于嵌套路由
  //   console.log(req, res, next)
  res.render(login())

  // 点击进行登录
  // 注意: res.render(login())执行之后,登录页面才渲染出来.才可以获取到对应的真实dom
  $('#loginBtn').on('click', async function (e) {
    e.preventDefault()
    // 获取用户输入的管理员账号和密码
    // 获取账号和密码
    const username = $('#loginForm input[type=text]').val().trim()
    const password = $('#loginForm input[type=password]').val().trim()
    // 进行表单校验
    if (!(/^\w{2,8}$/.test(username) && /^\w{6,8}$/.test(password)))
      return toastr.error('请输入正确的用户名或密码')

    // 发送请求,进行登录
    const result = await reqLogin(username, password)
    // console.log(result)
    if (result.success) {
      // 存储token到localStorage里面
      localStorage.setItem('authorization', result.token)
      // 跳转到首页
      res.redirect('/index', result.admin)
    } else {
      toastr.error(result.msg)
    }
  })
})
router.route('/index', async (req, res, next) => {
  await isEnableToken(res)

  // 打开首页之前,先判断token是否有效,如果无效,则直接return,后面代码不执行
  // const verifyResult = await reqVerifyToken()
  // if (!verifyResult.success) {
  //   //提示用户
  //   toastr.error(verifyResult.msg)
  //   //重定向登录
  //   res.redirect('/login')
  //   // 阻止后面代码执行
  //   return
  // }

  // 由于一级路由/index中嵌套了二级路由,所以必须使用next将匹配路径传递下去
  next(
    index({
      subRoute: res.subRoute(),
      url: req.url, // 将当前浏览器地址栏的路径传递到模板中
      // 传入登录的用户的用户名
      admin: req.body,
    })
  )

  // 给退出按钮,注册点击事件. 1. 给服务器发送请求,删除数据库中当前用户的token. 2 删除localStorage的token
  $('#logoutBtn').on('click', async function () {
    // 获取当前用户的id
    const id = $('#logoutBtn')[0].dataset.id
    // 发送请求
    await reqlogout(id)
    // 清除本地的token
    localStorage.clear()
    // 跳转到login页面
    res.redirect('/login')
  })
})
// 配置二级路由时,要在二级路由的路径前面拼接一级路由的路径
router.route('/index/adminList', async (req, res, next) => {
  // 打开首页之前,先判断token是否有效,如果无效,则直接return,后面代码不执行
  // const verifyResult = await reqVerifyToken()
  // if (!verifyResult.success) {
  //   //提示用户
  //   toastr.error(verifyResult.msg)
  //   //重定向登录
  //   res.redirect('/login')
  //   // 阻止后面代码执行
  //   return
  // }

  await isEnableToken(res)
  // 一旦打开管理员列表界面,立刻发送请求获取管理员数据
  const result = await getAdmins()
  console.log(result)
  if (result.success) {
    res.render(adminList({ adminList: result.data }))
  } else {
    toastr.error(result.msg)
  }
})
router.route('/index/advList', async (req, res, next) => {
  // 打开首页之前,先判断token是否有效,如果无效,则直接return,后面代码不执
  await isEnableToken(res)

  //获取广告数据
  const result = await getAdvs()

  res.render(advList({ advList: result.data }))
  //添加广告功能:  获取保存按钮, 注册点击事件,在事件处理函数中,上传广告信息到服务器
  $('#saveAdv').on('click', async function () {
    // 1. 创建formdata
    // 获取form Dom对象
    const formdata = new FormData($('#form')[0])
    const title = formdata.get('advTitle')
    const category = formdata.get('advCategory')
    const link = formdata.get('advLink')
    const file = formdata.get('file')
    // 添加广告和修改广告的按钮是同一个.所以要判断当前是添加还是修改
    if (this.innerText === '保存') {
      // 2. 进行表单校验.

      if (!(title && category && link && file.size))
        return toastr.error('请正确填写表单')
      // 3. 发送请求
      const result = await reqAddAdv(formdata)
      // 响应完成之后,判断是否成功
      if (result.success) {
        toastr.success(result.msg)
        res.redirect('/index/advList')
      } else {
        toastr.error(result.msg)
      }
    } else {
      if (!(title && category && link)) return toastr.error('请正确填写表单')
      // 往formdata里面添加要修改的数据的id
      const id = this.dataset.id
      formdata.append('id', id)
      const result = await reqUpdateAdv(formdata)
      if (result.success) {
        toastr.success(result.msg)
        res.redirect('/index/advList')
      }
    }
  })

  // 预览图片
  $('#file').on('change', (e) => {
    //判断是否有文件
    if (!e.target.files.length) return ($('#preShow')[0].style.display = 'none')
    // 获取要上传的文件对象
    const file = e.target.files[0]

    // 1. 创建reader对象
    const reader = new FileReader()
    // // 2. 使用reader对象,读取刚刚选中的文件
    reader.readAsDataURL(file)
    // reader有一个onload事件,读取完毕之后,会触发.
    reader.onload = function (e) {
      // e.target.result的值就是读取的文件对象,转成base64的结果
      const imgData = e.target.result
      $('#preShow')[0].src = imgData
      $('#preShow')[0].style.display = 'block'
    }
  })

  // 删除一条广告信息
  $('#tbody .btn-danger').on('click', async function () {
    const id = this.dataset.id
    await deleteAdv(id)
    res.redirect('/index/advList')
  })

  // 修改一条广告信息
  $('#tbody .btn-primary').on('click', async function () {
    // 修改模态框的标题和按钮的文本
    $('.modal-title').text('修改广告')
    // 修改保存按钮的文本
    $('#saveAdv').text('修改')

    // 发送请求,获取当前广告的信息
    // 获取id
    const id = this.dataset.id
    const result = await getOneAdv(id)
    // 拿到数据之后,动态的将广告信息,展示在模态框中
    $('input[name=advTitle]').val(result.adv.advTitle)
    $('input[name=advCategory]').val(result.adv.advCategory)
    $('input[name=advLink]').val(result.adv.advLink)
    $('#preShow')[0].src = result.adv.advAvatar
    $('#preShow')[0].style.display = 'block'

    // 点击修改按钮时,往模态框中的修改按钮上,添加一个当前广告的id
    $('#saveAdv')[0].dataset.id = id
  })

  // 给添加广告按钮注册点击事件,事件处理函数中修改模态框的内容
  $('#addAdvBtn').on('click', function () {
    // 修改模态框的标题和按钮的文本
    $('.modal-title').text('添加广告')
    $('#saveAdv').text('保存')
    // 把表单项中的值都清空(重置表单)
    $('#form')[0].reset()
    // 隐藏预览图片的img
    $('#preShow')[0].style.display = 'none'
  })
})
// * 表示配置的路径之外的所有其他路径
router.route('*', (req, res, next) => {
  res.redirect('/login')
})
